﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PMS.ENT;
using PMS.Utilities;
using PMS.BLL;
using System.IO;
using System.Text;
using System.IO.Compression;
using Ionic.Zip;
using Ionic.Zlib;

namespace PMS.Controllers
{
    public class ReferenceController : Controller
    {
        //
        // GET: /Reference/
      
        #region List
        public ActionResult ManageReference()
        {
            try
            {
                #region Permission
                //if (Session["UserID"] == null || Utility.IntParse(Session["UserID"]) <= 0)
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                //if (Utility.UserID <= 0 || Utility.RoleID <= 0 || string.IsNullOrWhiteSpace(Utility.Role))
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                #endregion

                #region LoadData
                int page = MvcApplication.pageDefault;
                int pageSize = MvcApplication.pageSizeDefault;
                int totalRecords = 0;
                int userID = 0;
                if (Utility.Role == Role.Teacher.ToString())
                {
                    userID = Utility.UserID;
                }
                ProjectCollection listProjet = ProjectBLL.GetProjectList(string.Empty, 0, 0, ProjectColumns.ProjectName.ToString(), OrderDirection.ASC.ToString(), page, pageSize, out totalRecords);

                LoadDataForList(0, 0);
                #endregion

                #region Pagination and search
                ViewData["ProjectName"] = string.Empty;
                ViewData["IsSearch"] = 0;
                ViewData["OrderBy"] = ProjectColumns.ProjectName.ToString();
                ViewData["OrderDirection"] = OrderDirection.ASC.ToString();
                ViewData["Page"] = page;
                ViewData["PageSize"] = pageSize;
                double PageNum = Math.Ceiling((double)totalRecords / pageSize);
                ViewData["PageNum"] = PageNum;
                ViewData["TotalRecord"] = totalRecords;

                if (totalRecords > 0)
                {
                    if (page == PageNum)
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), totalRecords.ToString(), totalRecords.ToString());
                    else
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), (pageSize * page).ToString(), totalRecords.ToString());
                }
                #endregion

                return View("Reference", listProjet);
            }
            catch (DataAccessException)
            {
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
            catch (Exception ex)
            {
                LogBLL.LogEx("BLM_ERR_Common", ex);
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
        }

        [HttpPost]
        public ActionResult ManageReference(int[] projectID, string action, int isSearch, string projectName, int subjectID, int departmentID, string orderBy, string orderDirection, int page, int pageSize)
        {
            try
            {
                #region Permission
                //if (Session["UserID"] == null || Utility.IntParse(Session["UserID"]) <= 0)
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                //if (Utility.UserID <= 0 || Utility.RoleID <= 0 || string.IsNullOrWhiteSpace(Utility.Role))
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                #endregion

                #region LoadData
                int totalRecords = 0;

                ProjectCollection listProjet = ProjectBLL.GetProjectList(projectName, departmentID, subjectID, orderBy, orderDirection, page, pageSize, out totalRecords);

                LoadDataForList(subjectID, departmentID);
                #endregion

                #region Pagination
                ViewData["ProjectName"] = projectName;
                ViewData["IsSearch"] = isSearch;
                ViewData["OrderBy"] = orderBy;
                ViewData["OrderDirection"] = orderDirection;
                ViewData["Page"] = page;
                ViewData["PageSize"] = pageSize;
                double PageNum = Math.Ceiling((double)totalRecords / pageSize);
                ViewData["PageNum"] = PageNum;
                ViewData["TotalRecord"] = totalRecords;

                if (totalRecords > 0)
                {
                    if (page == PageNum)
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), totalRecords.ToString(), totalRecords.ToString());
                    else
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), (pageSize * page).ToString(), totalRecords.ToString());
                }
                #endregion

                return View("Reference", listProjet);
            }
            catch (DataAccessException ex)
            {
                TempData[PageInfo.Message.ToString()] = ex.Message;
                return RedirectToAction("Error", "Home"); ;
            }
            catch (Exception ex)
            {
                LogBLL.LogEx("BLM_ERR_Common", ex);
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
        }


        #endregion

        #region Reference
        public ActionResult Reference(int ID)
        {
            try
            {
                #region Permission
                //if (Session["UserID"] == null || Utility.IntParse(Session["UserID"]) <= 0)
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                //if (Utility.UserID <= 0 || Utility.RoleID <= 0 || string.IsNullOrWhiteSpace(Utility.Role))
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                #endregion

                #region LoadData
                int page = MvcApplication.pageDefault;
                int pageSize = MvcApplication.pageSizeDefault;
                int totalRecords = 0;
                int userID = 0;
                if (Utility.Role == Role.Teacher.ToString())
                {
                    userID = Utility.UserID;
                }

                ReferenceCollection listReference = ReferenceBLL.GetReferenceList(ID, ReferenceColumns.FileName.ToString(), OrderDirection.ASC.ToString(), page, pageSize, out totalRecords);
                LoadDataForList(0, 0);
                #endregion

                #region Pagination and search
                ViewData["OrderBy"] = ProjectColumns.ProjectName.ToString();
                ViewData["OrderDirection"] = OrderDirection.ASC.ToString();
                ViewData["Page"] = page;
                ViewData["PageSize"] = pageSize;
                double PageNum = Math.Ceiling((double)totalRecords / pageSize);
                ViewData["PageNum"] = PageNum;
                ViewData["TotalRecord"] = totalRecords;

                if (totalRecords > 0)
                {
                    if (page == PageNum)
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), totalRecords.ToString(), totalRecords.ToString());
                    else
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), (pageSize * page).ToString(), totalRecords.ToString());
                }
                #endregion

                return View("ReferenceDetail", listReference);
            }
            catch (DataAccessException)
            {
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
            catch (Exception ex)
            {
                LogBLL.LogEx("BLM_ERR_Common", ex);
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
        }

        [HttpPost]
        public ActionResult Reference(int ID, int[] referenceID, string action, string orderBy, string orderDirection, int page, int pageSize)
        {
            try
            {
                #region Permission
                //if (Session["UserID"] == null || Utility.IntParse(Session["UserID"]) <= 0)
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                //if (Utility.UserID <= 0 || Utility.RoleID <= 0 || string.IsNullOrWhiteSpace(Utility.Role))
                //{
                //    return RedirectToAction("Login", "Home");
                //}

                #endregion

                #region Do Action
                if (action == ActionName.Delete.ToString())
                {

                    if (ReferenceBLL.DeleteReference(Utility.StringParse(referenceID), Utility.UserID) > 0)
                    {
                        TempData["Message"] = "Success, delete!";
                    }

                    else
                    {
                        TempData["Message"] = "Error, cannot delete references are not yours!";
                    }
                }
                else if (action == ActionName.Show.ToString())
                {
                    if (ReferenceBLL.ShowReference(Utility.StringParse(referenceID), Utility.UserID) > 0)
                    {
                        TempData["Message"] = "Success, update status!";
                    }

                    else
                    {
                        TempData["Message"] = "Error, update status!";
                    }
                }
                else if (action == ActionName.Hide.ToString())
                {
                    if (ReferenceBLL.HideReference(Utility.StringParse(referenceID), Utility.UserID) > 0)
                    {
                        TempData["Message"] = "Success, update status!";
                    }

                    else
                    {
                        TempData["Message"] = "Error, update status!";
                    }
                }
                else if (action == ActionName.Download.ToString())
                {
                    ReferenceCollection listRef = ReferenceBLL.GetReferenceList(Utility.StringParse(referenceID));
                    
                    ZipFile zip = new ZipFile();
                    string filePath = Server.MapPath("~/Reference");
                    string filename = Path.Combine(filePath, DateTime.Today.ToString("dd_MM_yyyy") + ".zip");
                    for (int i = 0; i < listRef.Count; i++)
                    {
                        FileInfo file = new FileInfo(Server.MapPath(listRef[i].FilePath));
                        if(file.Exists)
                        {
                            zip.AddFile(Server.MapPath(listRef[i].FilePath),ID.ToString());
                        }
                    }

                    zip.Save(filename);

                    FileInfo fileZip = new FileInfo(filename);
                    Stream stream = fileZip.OpenRead();
                    Response.AddHeader("content-dispostion", "attachemnt; filename=AllFile.zip");
                    Response.AddHeader("content-type", "application/zip");
                    stream.Seek(0, System.IO.SeekOrigin.Begin);

                    byte[] fileData = new byte[stream.Length];
                    stream.Read(fileData, 0, (int)stream.Length);

                    Response.AddHeader("Content-Length", stream.Length.ToString());
                    Response.BinaryWrite(fileData);
                    stream.Close();
                }
                
                #endregion

                #region LoadData
                int totalRecords = 0;

                ReferenceCollection listReference = ReferenceBLL.GetReferenceList(ID, orderBy, orderDirection, page, pageSize, out totalRecords);

                #endregion

                #region Pagination
                ViewData["OrderBy"] = orderBy;
                ViewData["OrderDirection"] = orderDirection;
                ViewData["Page"] = page;
                ViewData["PageSize"] = pageSize;
                double PageNum = Math.Ceiling((double)totalRecords / pageSize);
                ViewData["PageNum"] = PageNum;
                ViewData["TotalRecord"] = totalRecords;

                if (totalRecords > 0)
                {
                    if (page == PageNum)
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), totalRecords.ToString(), totalRecords.ToString());
                    else
                        ViewData["PageInfo"] = string.Format(" {0} - {1} / {2}.", (((page - 1) * pageSize) + 1).ToString(), (pageSize * page).ToString(), totalRecords.ToString());
                }
                #endregion

                return View("ReferenceDetail", listReference);
            }
            catch (DataAccessException ex)
            {
                TempData[PageInfo.Message.ToString()] = ex.Message;
                return RedirectToAction("Error", "Home"); ;
            }
            catch (Exception ex)
            {
                LogBLL.LogEx("BLM_ERR_Common", ex);
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
        }


        #endregion

        #region LoadData

        public void LoadDataForList(int subjectID, int departmentID)
        {
            ViewData["SubjectList"] = new SelectList(SubjectBLL.GetSubjectListForCMB(0), SubjectColumns.SubjectID.ToString(), SubjectColumns.SubjectName.ToString(), subjectID);
            ViewData["DepartmentList"] = new SelectList(DepartmentBLL.GetDepartmentListForCMB(), DepartmentColumns.DepartmentID.ToString(), DepartmentColumns.DepartmentName.ToString(), departmentID);

        }
        public void LoadDataForProgressList(int projectID, int scheduleID, int groupID, int semesterID)
        {
            ViewData["ProjectList"] = new SelectList(ProjectBLL.GetProjectListForCMB(0), ProjectColumns.ProjectID.ToString(), ProjectColumns.ProjectName.ToString(), projectID);
            ViewData["ScheduleList"] = new SelectList(ScheduleBLL.GetScheduleListForCMB(0, projectID, semesterID), ScheduleColumns.ScheduleID.ToString(), ScheduleColumns.ScheduleName.ToString(), scheduleID);
            ViewData["GroupList"] = new SelectList(GroupBLL.GetGroupListForCMB(0, projectID), GroupColumns.GroupID.ToString(), GroupColumns.GroupName.ToString(), groupID);
            ViewData["SemesterList"] = new SelectList(SemesterBLL.GetSemesterListForCMB(), SemesterColumns.SemesterID.ToString(), SemesterColumns.SemesterName.ToString(), semesterID);

        }

        public void LoadDataForUpLoad(ScheduleItemCollection listScheduleItem)
        {
            List<MarkENT> listMark = new List<MarkENT>();

            listMark.Add(new MarkENT { Name = "", Value = 0 });
            listMark.Add(new MarkENT { Name = "1", Value = 1 });
            listMark.Add(new MarkENT { Name = "2", Value = 2 });
            listMark.Add(new MarkENT { Name = "3", Value = 3 });
            listMark.Add(new MarkENT { Name = "4", Value = 4 });
            listMark.Add(new MarkENT { Name = "5", Value = 5 });
            listMark.Add(new MarkENT { Name = "6", Value = 6 });
            listMark.Add(new MarkENT { Name = "7", Value = 7 });
            listMark.Add(new MarkENT { Name = "8", Value = 8 });
            listMark.Add(new MarkENT { Name = "9", Value = 9 });
            listMark.Add(new MarkENT { Name = "10", Value = 10 });

            for (int i = 0; i < listScheduleItem.Count; i++)
            {
                int value = Convert.ToInt32(listScheduleItem[i].Mark);
                ViewData["ListMark" + i] = new SelectList(listMark, MarkColumns.Value.ToString(), MarkColumns.Name.ToString(), value);
            }

        }
        #endregion

        #region DownloadAll
        public ActionResult DownloadAllFile(int scheduleID, int groupID)
        {

            try
            {
                ZipFile zip = new ZipFile();
                string filePath = Server.MapPath("~/Upload");
                filePath = Path.Combine(Server.MapPath("~/Upload"), scheduleID.ToString(), groupID.ToString());
                string filename = Path.Combine(filePath, "AllFile.zip");
                if (Directory.Exists(filePath))
                {
                    zip.AddDirectory(filePath);
                    zip.Save(filename);
                }
                else
                {
                    TempData["Message"] = "Error, No content found!";
                    return RedirectToAction("Reference");
                }
                FileInfo file = new FileInfo(filename);
                Stream stream = file.OpenRead();
                Response.AddHeader("content-dispostion", "attachemnt; filename=AllFile.zip");
                Response.AddHeader("content-type", "application/zip");
                stream.Seek(0, System.IO.SeekOrigin.Begin);

                byte[] fileData = new byte[stream.Length];
                stream.Read(fileData, 0, (int)stream.Length);

                Response.AddHeader("Content-Length", stream.Length.ToString());
                Response.BinaryWrite(fileData);
                stream.Close();
                return null;
            }
            catch (DataAccessException)
            {
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
            catch (Exception ex)
            {
                LogBLL.LogEx("BLM_ERR_Common", ex);
                TempData[PageInfo.Message.ToString()] = "BLM_ERR_Common";
                return RedirectToAction("Error", "Home");
            }
        }

        #endregion

        #region Upload
        public JsonResult UploadFile(int? projectID, int? isHide, HttpPostedFileBase qqfile)
        {
            int statementID = 0;
            string filePath = string.Empty;

            filePath = Path.Combine(Server.MapPath("~/Reference"), projectID.ToString());

            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }

            ReferenceENT file = new ReferenceENT();
            if (qqfile != null)
            {
                // this works for IE
                var filename = Path.Combine(filePath, Path.GetFileName(qqfile.FileName));
                qqfile.SaveAs(filename);
                FileInfo fileInfo = new FileInfo(filename);
                InsertFile(fileInfo, projectID ?? 0, filename, isHide ?? 0, out file);
                return Json(new { success = true, statementID = statementID, Name = file.FileName, fileInfo = file }, "text/plain");
            }
            else
            {
                // this works for Firefox, Chrome
                var filename = Request["qqfile"];

                if (!string.IsNullOrEmpty(filename))
                {
                    filename = Path.Combine(filePath, Path.GetFileName(filename));
                    using (var output = System.IO.File.Create(filename))
                    {
                        Request.InputStream.CopyTo(output);
                        FileInfo fileInfo = new FileInfo(filename);
                        InsertFile(fileInfo, projectID ?? 0, filename, isHide ?? 0, out file);
                    }
                    return Json(new { success = true, statementID = statementID, fileInfo = file }, "text/plain");
                }
            }
            return Json(new { success = false });
        }

        public void InsertFile(FileInfo fileInfo, int projectID, string filePath, int isHide, out ReferenceENT file)
        {
            try
            {
                filePath = filePath.Remove(0, filePath.IndexOf("Reference"));
                filePath = @"../../" + filePath.Replace("\\", "/");
                file = new ReferenceENT
                {
                    ReferenceID = 0,
                    ProjectID = projectID,
                    OwnerID = Utility.UserID,
                    FileName = fileInfo.Name,
                    FilePath = filePath,
                    FileSize = fileInfo.Length,
                    IsHide = isHide,
                    CreatedBy = Utility.UserID,
                    UpdateBy = Utility.UserID,
                    Isdeleted = 0,
                };
                if (ReferenceBLL.InsertReference(file) <= 0)
                {
                    throw new DataAccessException("BLM_ERR_InsertReference");
                }
            }
            catch (Exception)
            {

                throw;
            }
        }

        #endregion

    }
}
